using System;
using System.Drawing;

using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Audio;

using OpenTK.Input;
using OpenTK.Math;
namespace Xeno.Core
{
    public class XenoApp : GameWindow
    {
        public static XenoRenderTarget FrameBufferTarget;
        public static XenoTexture2D FrameBuffer;
        public static XenoTextureDepth FrameDepth;
        public static XenoApp Instance = null;
        public static double FrameTime = 0.0f;
        /// <summary>Creates a 800x600 window with the specified title.</summary>
        public XenoApp()
            : base(800, 600, GraphicsMode.Default, "OpenTK Quick Start Sample")
        {
            VSync = VSyncMode.Off;
            XenoCore.DisplayWidth = Width;
            XenoCore.DisplayHeight = Height;
            ResetEngine();
        }

        public XenoApp(int width, int height, string title)
            : base(width, height, GraphicsMode.Default, title)
        {
            VSync = VSyncMode.Off;
            XenoCore.DisplayWidth = width;
            XenoCore.DisplayHeight = height;
            ResetEngine();
        }

        public void ResetEngine()
        {
            Instance = this;
            XenoCore.CurrentApp = this;
            XenoCore.CurrentScene = new XenoGraph();
            XenoCore.CurrentView = XenoFactory.Node.Camera("View Camera", XenoCore.CurrentScene.RootNode);
            XenoInput.Init();
            XenoText.Init();
            FrameBufferTarget = new XenoRenderTarget();
            FrameBuffer = new XenoTexture2D((int)XenoCore.DisplayWidth, (int)XenoCore.DisplayHeight);
            FrameDepth = new XenoTextureDepth((int)XenoCore.DisplayWidth, (int)XenoCore.DisplayHeight);

        }

        /// <summary>Load resources here.</summary>
        /// <param name="e">Not used.</param>
        public override void OnLoad(EventArgs e)
        {
            GL.ClearColor(System.Drawing.Color.MidnightBlue);
            GL.Enable(EnableCap.DepthTest);
            DoInit();
        }

        public XenoNode RootNode()
        {
            return XenoCore.CurrentScene.RootNode;
        }

        public virtual void DoInit()
        {

        }

        public virtual void DoUpdate()
        {

        }
        public virtual void DoPreRender()
        {
        }
        public virtual void DoPostRender()
        {

        }

        protected override void OnResize(OpenTK.Platform.ResizeEventArgs e)
        {
            GL.Viewport(new Rectangle(0, 0, e.Width, e.Height));

            Matrix4 projection = Matrix4.Perspective((float)Math.PI / 4, Width / (float)Height, 1.0f, 64.0f);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref projection);
        }
        /// <summary>
        /// Called when your window is resized. Set your viewport here. It is also
        /// a good place to set up your projection matrix (which probably changes
        /// along when the aspect ratio of your window).
        /// </summary>
        /// <param name="e">Contains information on the new Width and Size of the GameWindow.</param>


        public override void OnUpdateFrame(UpdateFrameEventArgs e)
        {
            FrameTime = e.Time;
           
            DoUpdate();
            XenoCore.CurrentScene.UpdateGraph();

        }


        public override void OnRenderFrame(RenderFrameEventArgs e)
        {
            XenoCore.LightList = XenoCore.CurrentScene.RootNode.AllWithType(typeof(XenoMod_Light), null);

            DoPreRender();

            XenoCore.CurrentScene.RootNode.PerformRender();

            DoPostRender();


            Frame++;
            if (Environment.TickCount > NextTick)
            {
                Fps = Frame;
                NextTick = Environment.TickCount + 1000;
                Frame = 0;
                Console.WriteLine("FPS:" + Fps);
            }
            SwapBuffers();

        }

        int Frame = 0;
        int NextTick = 0;
        int Fps = 0;



    }

}